home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HyperLib 1997 Winter - Disc 1
/
HYPERLIB-1997-Winter-CD1.ISO.7z
/
HYPERLIB-1997-Winter-CD1.ISO
/
第1特集Plug-in
/
Photoshop
/
Ster_ DropIns Folder.sit
/
Ster_ DropIns Folder
/
NIH-Image
/
Stereology…
Wrap
Text File
|
1995-03-06
|
12KB
|
422 lines
{Manual stereology macros for NIH Image.
Overlay grids on an image with arrays of lines or points (reports
the number of points or the length of the lines in image units).
Grids provided include three different point arrays and four
line arrays, one of which is cycloids for vertical section method.
Then use paintbrush set to any of the fixed colors (up to 6)
to mark locations to be counted (e.g., where line grids cross
feature boundaries). Finally, use macro to count marks in each
class, and use results for stereological calculations.
For more details, see the paper "Computer-Assisted Manual Stereology"
in Journal of Computer Assisted Microscopy, vol. 7 #1, p. 1, Mar. 1995
ゥ 1995 John C. Russ - may be freely distributed if the documentation
is included.}
Macro 'Point Grid';
Var
k,x,y,xoff,pwd,pht,nrow,ncol:integer;
area,ppx:real;
un:string;
Begin
GetPicSize(pwd,pht);
NRow:=pht div 50;
NCol:=pwd div 50;
XOff:=(pwd - 50*NCol) div 2;
if XOff<25 THEN XOff:=25;
y:=(pht - 50*NRow) div 2;
if y<25 THEN y:=25;
Setlinewidth(1);
k:=0;
repeat {until >pht}
x:= XOff;
repeat {until >pwd}
MoveTo (x-5, y);
LineTo (x-1, y);
MoveTo (x+1, y);
LineTo (x+5, y);
MoveTo (x, y-5);
LineTo (x, y-1);
MoveTo (x, y+1);
LineTo (x, y+5);
k:=k+1; {counter}
x:=x+50;
until ((x+10)>pwd);
y:=y+50;
until ((y+20)>pht);
GetScale(ppx,un);
MoveTo (2,pht-6);
SetFont('Geneva');
SetFontSize(10);
Write('Total Points=',k:3);
Area:=pwd*pht/(ppx*ppx);
Moveto (2,pht-18);
Write('Total Area=',Area:10:3,'sq.',un);
End;
Macro 'Staggered Grid';
Var
i,k,x,y,xoff,yoff,pwd,pht,nrow,ncol:integer;
area,ppx:real;
un:string;
Begin
GetPicSize(pwd,pht);
nrow:=pht div 34;
ncol:=pwd div 50;
XOff:=(pwd - 50*NCol) div 2;
if XOff<25 THEN XOff:=25;
YOff:=(pht - 34*NRow) div 2;
if yoff<25 THEN yoff:=25;
setlinewidth(1);
k:=0;
i:=0;
y:=yoff;
repeat {until >height}
x:= XOff;
IF (2*(i div 2)=i)
THEN x:= x + 25;
repeat {until >width}
MoveTo (x-5, y);
LineTo (x-2, y);
MoveTo (x+2, y);
LineTo (x+5, y);
MoveTo (x, y-5);
LineTo (x, y-2);
MoveTo (x, y+2);
LineTo (x, y+5);
MakeOvalRoi(x-2,y-2,5,5);
DrawBoundary;
KillRoi;
k:=k+1; {counter}
x:=x+50;
until ((x+25)>pwd);
y:=y+34;
i:=i+1;
until ((y+25)>pht);
GetScale(ppx,un);
MoveTo (2,pht-6);
SetFont('Geneva');
SetFontSize(10);
Write('Total Points=',k:3);
Area:=pwd*pht/(ppx*ppx);
Moveto (2,pht-18);
Write('Total Area=',Area:10:3,'sq.',un);
END;
Macro 'Cycloids';
Var
h,i,j,k,x,y,xoff,yoff,pwd,pht,nrow,ncol,xstep,ystep:integer;
len,area,ppx,pi,theta:real;
un:string;
Begin
pi:=3.14159265;
GetPicSize(pwd,pht);
NRow:=pht div 90;
NCol:=pwd div 130;
XOff:=(pwd - 130*NCol) div 2;
YOff:=(pht - 90*NRow) div 2;
{cycloids are 110 wide x 70 high, length 140}
setlinewidth(1);
h:=0;
FOR j:=1 to NRow DO
BEGIN
y:=yoff + j*90-10;
For i:=1 to ncol DO
BEGIN
x:=xoff+(i-1)*130+10;
IF (h mod 4)=0 THEN
BEGIN
MoveTo (x,y);
For k := 1 to 40 DO
BEGIN
theta:=(pi/40) *k;
xstep:=round(35*(theta-sin(theta)));
ystep:=round(35*(1.0-cos(theta)));
Lineto (x+xstep,y-ystep);
END;
END;
IF (h mod 4)=1 THEN
BEGIN
MoveTo (x,y-70);
For k := 1 to 40 DO
BEGIN
theta:=(pi/40) *k;
xstep:=round(35*(theta-sin(theta)));
ystep:=round(35*(1.0-cos(theta)));
Lineto (x+xstep,y-70+ystep);
END;
END;
IF (h mod 4)=2 THEN
BEGIN
MoveTo (x+110,y);
For k := 1 to 40 DO
BEGIN
theta:=(pi/40) *k;
xstep:=round(35*(theta-sin(theta)));
ystep:=round(35*(1.0-cos(theta)));
Lineto (x+110-xstep,y-ystep);
END;
END;
IF (h mod 4)=3 THEN
BEGIN
MoveTo (x+110,y-70);
For k := 1 to 40 DO
BEGIN
theta:=(pi/40) *k;
xstep:=round(35*(theta-sin(theta)));
ystep:=round(35*(1.0-cos(theta)));
Lineto (x+110-xstep,y-70+ystep);
END;
END;
h:=h+1;
END; {for i}
END; {for j}
GetScale(ppx,un);
Len:=h*140/ppx;
MoveTo (2,pht-6);
SetFont('Geneva');
SetFontSize(10);
Write('Total Length=',Len:10:4,' ',un);
Area:=pwd*pht/(ppx*ppx);
Moveto (2,pht-18);
Write('Total Area=',Area:10:3,' sq.',un);
END;
Macro 'Square Lines';
Var
i,j,x,y,xoff,yoff,pwd,pht,nrow,ncol:integer;
len,area,ppx:real;
un:string;
Begin
GetPicSize(pwd,pht);
NRow:=pht div 100;
NCol:=pwd div 100;
XOff:=(pwd - 100*NCol) div 2;
YOff:=(pht - 100*NRow) div 2;
if XOff=0 THEN
BEGIN
XOffset:=50;
ncol:=ncol-1;
END;
if yoff=0 THEN
BEGIN
yoff:=50;
nrow:=nrow-1;
END;
setlinewidth(1);
For j:=0 to NRow DO
BEGIN
y:= YOff + j*100;
MoveTo (xoff, y);
LineTo (pwd-xoff-1, y);
END;
For i:=0 to ncol DO
BEGIN
x:= XOff + i*100;
MoveTo (x,YOff);
LineTo (x,pht-YOff-1);
END;
GetScale(ppx,un);
Len:=(NRow*(Ncol+1)+NCol*(Nrow+1))*100/ppx;
MoveTo (2,pht-6);
SetFont('Geneva');
SetFontSize(10);
Write('Total Length=',Len:10:4,' ',un);
Area:=pwd*pht/(ppx*ppx);
Moveto (2,pht-18);
Write('Total Area=',Area:10:3,' sq.',un);
END;
Macro 'Circle Grid';
var
i,j,x,y,xoff,yoff,pwd,pht,nrow,ncol:integer;
len,area,ppx,pi:real;
un:string;
begin
GetPicSize(pwd,pht);
setlinewidth(1);
pi:=3.14159265;
NRow:=pht div 120;
NCol:=pwd div 120;
XOff:=(pwd - 130*ncol) div 2;
YOff:=(pht - 130*NRow) div 2;
For j:=1 to NRow DO
BEGIN
y:= YOff + 15 + (j-1)*130;
For i:=1 to NCol DO
BEGIN
x:= XOff + 15 + (i-1)*130;
MakeOvalRoi(x,y,101,101);
DrawBoundary;
KillRoi;
END;
END;
GetScale(ppx,un);
Len:=NRow*NCol*pi*100/ppx;
MoveTo (2,pht-6);
SetFont('Geneva');
SetFontSize(10);
Write('Total Length=',Len:10:4,' ',un);
Area:=pwd*pht/(ppx*ppx);
Moveto (2,pht-18);
Write('Total Area=',Area:10:3,' sq.',un);
END;
Macro '(-';
BEGIN END;
Macro 'Random Points';
Var
x,y,k,i,pwd,pht,limt:integer;
ppx,area:real;
un:string;
collide:boolean;
Begin
GetPicSize(pwd,pht);
limt:=50;{number of points}
k:=1;
repeat
x:=random*(pwd-20); {10 pixel margin around borders}
y:=random*(pht-20);
collide:=false;
if k>1 then {avoid existing marks}
for i:=1 to k-1 do
if (Abs(x-rUser1[i])<5) and (Abs(y-rUser2[i])<5)
then collide:=true;
if not collide then
begin
rUser1[k]:=x;
rUser2[k]:=y;
MakeOvalRoi(x+6,y+6,7,7);
DrawBoundary;
KillRoi;
k:=k+1;
end;
until (k>limt);
GetScale(ppx,un);
Area:=pwd*pht/(ppx*ppx);
SetFont('Geneva');
SetFontSize(10);
Moveto (2,pht-18);
Write('Total Area=',Area:10:3,'sq.',un);
Moveto (2,pht-6);
Write('Total Points=',k-1:4);
End;
Macro 'Random Lines';
Var
x,y,theta,m,area,ppx,dummy:real;
i,j,k,x1,x2,y1,y2,pwd,pht:integer;
len,limt:integer;
un:string;
Begin
GetPicSize(pwd,pht);
len:=0;
k:=0;
limt:=3*(pwd+pht); {minimum total length in pixels}
repeat {until length>limt}
x:=random*pwd;
y:=random*pht;
theta:=random*3.14159265;
m:=sin(theta)/cos(theta);
x1:=0;
y1:=y+m*(x1-x);
if y1<0 then
begin
y1:=0;
x1:=x+(y1-y)/m;
end;
if y1>pht then
begin
y1:=pht;
x1:=x+(y1-y)/m;
end;
x2:=pwd;
y2:=y+m*(x2-x);
if y2<0 then
begin
y2:=0;
x2:=x+(y2-y)/m;
end;
if y2>pht then
begin
y2:=pht;
x2:=x+(y2-y)/m;
end;
moveto(x1,y1);
lineto(x2,y2);
len:=len+sqrt((x2-x1)*(x2-x1)+(y1-y2)*(y1-y2))
k:=k+1;
until len>limt;
GetScale(ppx,un);
Area:=pwd*pht/(ppx*ppx);
SetFont('Geneva');
SetFontSize(10);
Moveto (2,pht-18);
Write('Total Area=',Area:10:3,'sq.',un);
Len:=Len/ppx;
Moveto (2,pht-6);
Write('Total Length=',Len:10:3,' ',un);
END;
Macro '(-';
BEGIN END;
Macro 'Count Marks'; {note - this routine is VERY slow because it must
access each pixel. The Photoshop drop-in is much faster for counting
features, and when used by NIH Image will perform exactly as this does
and count the number of marks in each of the six reserved colors.}
VAR
i,j,k,pwd,pht,valu,nbr,newfeat : integer;
BEGIN
GetPicSize(pwd,pht);
For i:= 1 to 6 DO
BEGIN
rUser1[i]:=0;
END;
MoveTo(0,0);
FOR i:=1 to pht DO
BEGIN
GetRow(0,i,pwd);
newfeat:=0; {start of a new image line - nothing pending}
for j:=1 to pwd-1 DO {skip edge pixels}
BEGIN
valu:=Linebuffer[j]; {test pixel}
if ((valu=0) or (valu>6)) THEN
BEGIN {pixel is not a fixed color}
if (newfeat>0) then {End of a line}
BEGIN
rUser1[newfeat]:=rUser1[newfeat]+1;
END;
newfeat:=0;
END;
if ((valu>=1) and (valu<=6)) then {a fixed color point}
BEGIN
nbr:=LineBuffer[j-1]; {left side}
if (nbr<>valu) THEN {test continuation of line}
BEGIN
if newfeat>0 then {prev touching color}
BEGIN
rUser1[newfeat]:=rUser1[newfeat]+1;
END;
newfeat:=valu;{start of a chord}
END;
for k:=j-1 to j+1 DO {check prev line}
BEGIN
nbr := GetPixel(k,i-1);
if (nbr = valu) then
BEGIN
newfeat:=0;{touches}
END;
END;
END;
END; {for j}
LineTo(0,i); {progress indicator because getpixel is very slow}
END; {for i}
Showmessage('Class#1=',rUser1[1]:3,'¥Class#2=',rUser1[2]:3,'¥Class#3=',rUser1[3]:3,
'¥Class#4=',rUser1[4]:3,'¥Class#5=',rUser1[5]:3,'¥Class#6=',rUser1[6]:3);
{can substitute other output procedures as needed}
END;